<template>
  <div class="wrapper">
    <div class="container">
      <div class="header-container">
        <!-- This heading also notifies about the theme change.-->
        <h1 id="toast">Calculator</h1>
      </div>
      <div class="first-row">
        <div class="show" :style="{}">
          <div class="innerShow" v-html="showRes" :style="{ overflow: 'scroll', marginTop: 3 }"></div>
        </div>
        <!-- <input type="text" name="result" placeholder="" readonly /> -->
      </div>
      <div class="second-row">
        <input type="button" value="1" @click="liveScreen(1)" />
        <input type="button" value="2" @click="liveScreen(2)" />
        <input type="button" value="3" @click="liveScreen(3)" />
        <input type="button" value="+" @click="liveScreen('+')" />
      </div>
      <div class="third-row">
        <input type="button" value="4" @click="liveScreen(4)" />
        <input type="button" value="5" @click="liveScreen(5)" />
        <input type="button" value="6" @click="liveScreen(6)" />
        <input type="button" value="-" @click="liveScreen('-')" />
      </div>
      <div class="fourth-row">
        <input type="button" value="7" @click="liveScreen(7)" />
        <input type="button" value="8" @click="liveScreen(8)" />
        <input type="button" value="9" @click="liveScreen(9)" />
        <input type="button" value="↩" @click="liveScreen('^')" />
      </div>
      <div class="fifth-row">
        <input type="button" value="C" @click="cleanRes" id="clear-button" />
        <input type="button" value="0" @click="liveScreen(0)" />
        <input type="button" value="&xscr;" @click="liveScreen('x')" />
        <input type="button" value="OK" @click="storeRes" />
      </div>
    </div>
    <div class="right">
      <div class="header-container">
        <h1 id="toast">Theme</h1>
        <div :style="{ width: 60 + 'px' }"></div>
        <img :src="icons[1]" />
        <el-switch v-model="theme" style="
            --el-switch-on-color: rgba(255, 255, 255, 0.5);
            --el-switch-off-color: rgba(255, 73, 73, 0.4);
          " :change="changeTheme()" />
        <img :src="icons[0]" />
      </div>

      <div class="header-container">
        <h1 id="toast">Polynomial</h1>
      </div>
      <ShowPolyn :click="inputStr" :op="0" :val="aStr" text="a" />
      <ShowPolyn :click="inputStr" :op="1" :val="bStr" text="b" />
      <ShowPolyn :click="inputStr" :op="2" :val="xStr" text="x" />

      <div class="header-container">
        <h1 id="toast">Result</h1>
        <div :style="{ width: 105 + 'px' }"></div>
        <button class="polynButton" @click="clean">♻</button>
        <!-- ✘✂☠🚮🧺🚽🗑♻ 🖥 ± ✔±🔁-->
        <button class="polynButton" @click="calculate">✔</button>
      </div>
      <div class="block">
        <el-carousel style="width: 350px;" indicator-position="outside" height="100px" :autoplay=false>
          <el-carousel-item>
            <ShowResult :val="valPlus" :polyn="plus" title="1. a + b" />
          </el-carousel-item>
          <el-carousel-item>
            <ShowResult :val="valSubtr" :polyn="subtr" title="2. a - b" />
          </el-carousel-item>
          <el-carousel-item>
            <ShowResult :val="valMulti" :polyn="multi" title="3. a * b" />
          </el-carousel-item>
          <el-carousel-item>
            <ShowResult :val="valADeri" :polyn="aDeri" title="4. a 求导" />
          </el-carousel-item>
          <el-carousel-item>
            <ShowResult :val="valBDeri" :polyn="bDeri" title="5. b 求导" />
          </el-carousel-item>
        </el-carousel>
      </div>

    </div>
  </div>
</template>

<script>
import ShowPolyn from "../components/showPolyn.vue";
import ShowResult from "../components/showResult.vue"
import Sun from "../assets/SunIcon.svg";
import Moon from "../assets/MoonIcon.svg";
import { multiply } from "./fft.js"

//脚标为次方数，数据为系数
var a = [];
var b = [];
var c = [];

export default {
  // data() 返回的属性将会成为响应式的状态并且暴露在 `this` 上
  data() {
    return {
      theme: true,
      icons: [Sun, Moon],

      showRes: "",
      calRes: "",

      currStr: 0,
      isSup: false,

      aStr: '',
      aCal: '',
      aSup: false,
      bStr: '',
      bCal: '',
      bSup: false,
      xStr: '',
      xCal: '',

      plus: 'polynomial',
      subtr: 'polynomial',
      multi: 'polynomial',
      aDeri: 'polynomial',
      bDeri: 'polynomial',

      valPlus: 1,
      valSubtr: 2,
      valMulti: 3,
      valADeri: 4,
      valBDeri: 5,
    };
  },

  components: {
    ShowPolyn,
    ShowResult
  },

  // methods 是一些用来更改状态与触发更新的函数
  // 它们可以在模板中作为事件监听器绑定
  methods: {
    //更换主题色
    changeTheme() {
      if (this.theme) {
        document.documentElement.style.setProperty("--theme_bg", "rgb(7, 210, 199)");
        document.documentElement.style.setProperty("--button", "#fff");
        document.documentElement.style.setProperty("--button_hover", "rgba(255, 255, 255, 0.5)");
        document.documentElement.style.setProperty("--button_border", "#fff");
        document.documentElement.style.setProperty("--button_hover_big", "rgb(37, 35, 59)");
        document.documentElement.style.setProperty("--input_botton", "rgb(122, 122, 122)");
        document.documentElement.style.setProperty("--input_button_hover", "rgb(37, 35, 59)");
        document.documentElement.style.setProperty("--input", "rgb(87, 87, 87)");
        document.documentElement.style.setProperty("--show", "rgb(255, 255, 255)");
      } else {
        document.documentElement.style.setProperty("--theme_bg", "rgb(20, 19, 19)");
        document.documentElement.style.setProperty("--button", "rgb(47, 51, 50)");
        document.documentElement.style.setProperty("--button_hover", "rgba(255, 25, 25, 0.3)");
        document.documentElement.style.setProperty("--button_border", "rgba(255, 25, 25, 0.5)");
        document.documentElement.style.setProperty("--button_hover_big", "rgb(101, 101, 101)");
        document.documentElement.style.setProperty("--input_botton", "#fff");
        document.documentElement.style.setProperty("--input_button_hover", "rgb(101, 101, 101)");
        document.documentElement.style.setProperty("--input", "rgb(255, 255, 255)");
        document.documentElement.style.setProperty("--show", "rgb(47, 51, 50)");
      }
    },

    //清空输入框
    cleanRes() {
      this.showRes = "";
      this.calRes = "";
      this.aSup = false
      this.bSup = false
      this.isSup = false
    },

    //输入
    liveScreen(val) {
      if (this.isSup) {
        var flag = /^\d+$/.test(val)
        if (val == "+" || val == "-" || val == "^") flag = true
        if (!flag) {
          console.log("输入不合法")
          return
        }
      }

      if (val == "^") {
        if (this.calRes[this.calRes.length - 1] == "-") {
          this.calRes = this.calRes.substring(0, this.calRes.length - 2)
        } else {
          this.calRes = this.calRes.substring(0, this.calRes.length - 1)
        }
      } else if (val == "-") {
        this.isSup = false
        this.calRes += "+-";
      } else {
        if (val == "+") this.isSup = false
        if (val == "x") this.isSup = true
        this.calRes += val;
      }

      this.showRes = ""
      for (var i = 0; i < this.calRes.length; i++) {
        if (this.calRes[i] == "x") {
          this.showRes += "&xscr;<sup>";
        } else if (this.calRes[i] == "+") {
          this.showRes += "</sup>+"
        } else if (this.calRes[i] == "-") {
          this.showRes = this.showRes.substring(0, this.showRes.length - 1)
          this.showRes += "-"
        } else {
          this.showRes += this.calRes[i]
        }
      }
    },

    //存储
    storeRes() {
      console.log(this.currStr)
      if (this.currStr == 0) {
        this.aCal = this.calRes;
        console.log("this.calRes:", this.calRes)
        this.calToArr(this.aCal, 0);
        console.log("aCal:", this.aCal)
        this.aStr = this.arrToshow(a)
        console.log("aStr:", this.aStr)
        this.aSup = this.isSup
        console.log("this.aSup:", this.isSup)
        console.log("this.aStr", this.aStr)
      } else if (this.currStr == 1) {
        this.bCal = this.calRes;
        this.calToArr(this.bCal, 1)
        this.bStr = this.arrToshow(b)
        this.bSup = this.isSup
      } else {
        this.xCal = this.calRes;
        var flag = /^\d+$/.test(this.xCal)
        if (flag || this.xCal == "x" || this.xCal == "") {
          if (this.xCal == "x") this.xCal = ""
          this.xStr = this.showRes
        } else {
          this.$message({
            showClose: true,
            message: '仅支持输入数字、x或保持为空'
          });
        }
      }

    },

    //选择输入
    inputStr(val) {
      if (val == 0) {
        this.isSup = this.aSup
        this.currStr = 0;
        this.showRes = this.aStr;
        this.calRes = this.aCal;
      } else if (val == 1) {
        this.isSup = this.bSup
        this.currStr = 1;
        this.showRes = this.bStr;
        this.calRes = this.bCal;
      } else {
        this.currStr = 2;
        this.showRes = this.xStr;
        this.calRes = this.xCal;
      }
    },

    //清空变量数据
    clean() {
      this.showRes = ""
      this.calRes = ""
      this.currStr = 0
      this.isSup = false

      this.aStr = ''
      this.aCal = ''
      this.aSup = false
      this.bStr = ''
      this.bCal = ''
      this.bSup = false
      this.xStr = ''
      this.xCal = ''

      this.plus = 'polynomial'
      this.subtr = 'polynomial'
      this.multi = 'polynomial'
      this.aDeri = 'polynomial'
      this.bDeri = 'polynomial'

      this.valPlus = 1
      this.valSubtr = 2
      this.valMulti = 3
      this.valADeri = 4
      this.valBDeri = 5
    },

    //多项式字符串数据存入数组
    calToArr(str, op) {
      console.log(str)
      if (str == "") {
        arr = [0]
      } else {
        var tmp = str.split("+");
        var arr = []
        var coef, expo;  // 系数， 指数

        for (var i = 0; i < tmp.length; i++) {
          if (tmp[i] == "") continue;

          var flag = false; //是否为负数
          if (tmp[i][0] == "-") {
            flag = true;
            tmp[i] = tmp[i].substring(1, tmp[i].length)
          }

          var xindex = tmp[i].indexOf("x")
          if (xindex == -1) {
            expo = 0;
            coef = tmp[i];
          } else if (xindex == 0) {
            tmp[i] == "x" ? expo = 1 : expo = tmp[i].substring(1, tmp[i].length)
            coef = 1;
          } else if (xindex == tmp[i].length - 1) {
            expo = 1
            coef = tmp[i].substring(0, tmp[i].length - 1)
          } else {
            expo = tmp[i].substring(xindex + 1, tmp[i].length)
            coef = tmp[i].substring(0, xindex)
          }

          if (flag) coef = "-" + coef
          arr[expo] == null ? arr[expo] = parseInt(coef) : arr[expo] += parseInt(coef);
        }

        for (var i = 0; i < arr.length; i++) {
          if (arr[i] == null) arr[i] = 0
        }
      }

      if (op == 0) {
        a = arr;
      } else if (op == 1) {
        b = arr;
      }
    },

    //数组渲染字符串
    arrToshow(arr) {
      var show = ""

      for (var i = arr.length - 1; i >= 0; i--) {
        if (arr[i] == 0) continue;

        var flag = false; //是否为负数
        if (arr[i] < 0) flag = true;

        if (i != arr.length - 1 && flag == false) show += "+"

        if (arr[i] == 1 && i != 0) {
          show += ""
        } else if (arr[i] == -1 && i != 0) {
          show += "-"
        } else {
          show += arr[i]
        }

        if (i == 0) {
          show += ""
        } else if (i == 1) {
          show += "&xscr;"
        } else {
          show += "&xscr;<sup>" + i + "</sup>"
        }
      }
      if (show == "") show = "0"
      return show
    },

    //计算
    calculate() {
      var xval = parseInt(this.xCal)

      console.log("calculate!")
      console.log("a:", a)
      console.log("b:", b)
      console.log("xval:", xval)

      //plus
      c = this.plusArr(a, b)
      this.plus = this.arrToshow(c)
      this.valPlus = this.toVal(c, xval)
      //substr
      c = this.subtrArr(a, b)
      this.subtr = this.arrToshow(c)
      this.valSubtr = this.toVal(c, xval)
      // 求导
      c = this.subDeri(a)
      a.length < 2 ? this.aDeri = 0 : this.aDeri = this.arrToshow(c)
      this.valADeri = this.toVal(c, xval)

      c = this.subDeri(b)
      b.length < 2 ? this.bDeri = 0 : this.bDeri = this.arrToshow(c)
      this.valBDeri = this.toVal(c, xval)
      //fft
      c = multiply(a, b)
      this.multi = this.arrToshow(c)
      this.valMulti = this.toVal(c, xval)
    },

    plusArr(arr, brr) {
      var len = 0
      var crr = []
      arr.length > brr.length ? len = arr.length : len = brr.length
      for (var i = 0; i < len; i++) {
        if (arr[i] == null) {
          crr[i] = brr[i]
        } else if (brr[i] == null) {
          crr[i] = arr[i]
        } else {
          crr[i] = arr[i] + brr[i]
        }
      }
      return crr;
    },

    subtrArr(arr, brr) {
      var len = 0
      var crr = []
      arr.length > brr.length ? len = arr.length : len = brr.length
      for (var i = 0; i < len; i++) {
        if (arr[i] == null) {
          crr[i] = -brr[i]
        } else if (brr[i] == null) {
          crr[i] = arr[i]
        } else {
          crr[i] = arr[i] - brr[i]
        }
      }
      return crr;
    },

    subDeri(arr) {
      var crr = []
      for (var i = 0; i < arr.length - 1; i++)
        crr[i] = arr[i + 1] * (i + 1)
      return crr
    },

    //秦九韶公式
    toVal(arr, x) {
      var ans = 0;
      for (var i = arr.length - 1; i >= 0; --i) {
        ans = ans * x + arr[i]
      }
      return ans
    }

  },

  mounted() {
    document.onkeydown = (e) => {
      console.log(e.key)

      //numbers
      if (e.key === "0") {
        this.liveScreen(0)
      } else if (e.key === "1") {
        this.liveScreen(1)
      } else if (e.key === "2") {
        this.liveScreen(2)
      } else if (e.key === "3") {
        this.liveScreen(3)
      } else if (e.key === "4") {
        this.liveScreen(4)
      } else if (e.key === "5") {
        this.liveScreen(5)
      } else if (e.key === "6") {
        this.liveScreen(6)
      } else if (e.key === "7") {
        this.liveScreen(7)
      } else if (e.key === "8") {
        this.liveScreen(8)
      } else if (e.key === "9") {
        this.liveScreen(9)
      } else if (e.key === "+" || e.key === "=") {
        this.liveScreen("+")
      } else if (e.key === "-") {
        this.liveScreen("-")
      }

      // operator
      if (e.key === "x") {
        this.liveScreen("x")
      } else if (e.key === "c") {
        this.cleanRes()
      } else if (e.key === "Enter") {
        this.storeRes()
      } else if (e.key === "Backspace") {
        this.liveScreen("^")
      } else if (e.key === "ArrowUp") {
        this.currStr == 0 ? this.currStr = 2 : this.currStr--
        this.inputStr(this.currStr)
      } else if (e.key === "ArrowDown") {
        this.currStr == 2 ? this.currStr = 0 : this.currStr++
        this.inputStr(this.currStr)
      } else if (e.code === "Space") {
        this.calculate()
      }

    }
  }
}
</script>

<style>
:root {
  --theme_bg: rgb(7, 210, 199);
  --button: #fff;
  --button_hover: rgba(255, 255, 255, 0.5);
  --button_hover_big: rgb(37, 35, 59);
  --button_border:  #fff;
  --input_botton: rgb(122, 122, 122);
  --input_botton_hover: rgb(37, 35, 59);
  --input: rgb(87, 87, 87);
  --show: rgb(255, 255, 255);

}

/* CSS Reset & Global Styles */
* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
  font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", "Open Sans";
  -webkit-appearance: none;
}

.wrapper {
  height: 100vh;
  width: 100%;
  display: flex;
  justify-content: center;
  flex-direction: row;
  align-items: center;
  background-color: var(--theme_bg);
  transition: 0.8s all;
}

h1 {
  margin-bottom: 1.5%;
  color: #fff;
  font-weight: normal;
}

.polyn {
  font-weight: 700;
  color: #fff;
  font-size: 1.1em;
}

.polynButton {
  padding: 5px;
  color: #fff;
  font-size: 1em;
  font-weight: 700;
  cursor: pointer;
  width: 35px;
  background-color: var(--theme_bg);
  /* border: none; */
  outline: none;
  border-radius: 200px;
  margin: 0.2em;
  border: 1px solid var(--button_border);
  transition: background-color 0.2s linear;
}

.polynButton:hover {
  background-color: var(--button_hover);
}

.container {
  width: 350px;
  display: flex;
  justify-content: center;
  flex-direction: column;
  align-items: center;
  margin-right: 20px;
}

.right {
  width: 350px;
  height: 457.15px;
  display: flex;
  /* justify-content: center; */
  flex-direction: column;
  align-items: center;
  /* background-color: var(--button_hover); */
  margin-left: 20px;
}

.header-container {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 80%;
  margin: 5px;
}

.top-buttons {
  display: flex;
  align-items: center;
}

.show {
  background-color: var(--show);
  width: 295px;
  /* display: inline-block; */
  padding: 25px;
  color: var(--input);
  font-size: 1em;
  cursor: pointer;
  border: none;
  outline: none;
  border-radius: 100px;
  margin: 0.2em;
  padding-bottom: 0px;
  height: 63.5px;
}

.innerShow::-webkit-scrollbar {
  width: 0 !important;
}

input {
  padding: 25px;
  color: var(--input);
  font-size: 1em;
  cursor: pointer;
  width: 70px;
  background-color: var(--button);
  border: none;
  outline: none;
  border-radius: 100px;
  margin: 0.2em;
}

.first-row {
  margin-bottom: 4px;
  display: flex;
}

.second-row,
.third-row,
.fourth-row,
.fifth-row {
  margin-bottom: 4px;
}

.innerShow::-webkit-scrollbar {
  width: 0 !important;
}

input[type="button"] {
  color: var(--input_botton);
}

#showSpan,
input[type="text"] {
  background-color: var(--show);
  /* width: 222.5px; */
}

input[type="button"]:hover {
  background-color: var(--button_hover_big);
  color: #fff;
  ;
}

#clear-button {
  color: #fff;
  ;
  background-color: rgb(255, 25, 25);
}

a {
  text-decoration: none;
  color: #fff;
  ;
}
</style>